/*
 * Copyright (C) 2014 Lucid Wolf
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.lucidhex.viewer;

import com.lucidhex.LucidBoard;
import com.lucidhex.hex.LucidBoardBounds;
import com.lucidhex.hex.PlaneCoord;
import java.awt.Point;

/**
 *
 * @author Wolf
 */
public class ViewOptions {
    private final double ROTATE_UNIT = 30.0/180.0*Math.PI;

    private PlaneCoord center = null;
    private double stupidRadius = 1.0;
    private double theta = 0.0;
    private ViewPortal vp;
    private LucidBoard board;
    private ViewTransform transform;
    public ViewOptions(ViewPortal vp, LucidBoard board){
        this.board = board;
        this.vp = vp;
        LucidBoardBounds bound = board.getBounds();
        center = bound.getCenter();
        stupidRadius = bound.getStupidRadius();
        update();
    }
    public final void update(){
        if(vp.isWorldLoaded()){
            if(center == null){
                LucidBoardBounds bound = board.getBounds();
                center = bound.getCenter();
                stupidRadius = bound.getStupidRadius();                
            }
            transform = new ViewTransform(vp.getSize(), center, stupidRadius, theta);
        }
    }
    public final void reset(){
        LucidBoardBounds bound = board.getBounds();
        center = bound.getCenter();
        setRadius(bound.getStupidRadius());
        theta = 0.0;
        vp.repaint();
    }
    public void zoom(Point start, Point end){
        PlaneCoord s = transform.reverseTransform(start);
        PlaneCoord e = transform.reverseTransform(end);
        center = new PlaneCoord(s, e);
        setRadius(0.5*Math.max(Math.abs(s.X()-e.X()),Math.abs(s.Y()-e.Y())));
        vp.repaint();
    }
    public void zoomOnly(double rot, Point end) {
        center = transform.reverseTransform(end);
        setRadius(stupidRadius/rot);
        vp.repaint();
    }
    public void pan(Point start, Point end){
        PlaneCoord s = transform.reverseTransform(start);
        PlaneCoord e = transform.reverseTransform(end);
        double dx = e.X() - s.X();
        double dy = e.Y() - s.Y();
        center = new PlaneCoord(center.X()-dx, center.Y()-dy);
        vp.repaint();
    }

    public PlaneCoord getCenter() {
        return center;
    }
    public double getRadius() {
        return stupidRadius;
    }
    public double getTheta(){
        return theta;
    }
    public boolean isInBounds(PlaneCoord sc){
        return true;
        //return Math.sqrt((sc.X()-center.X())*(sc.X()-center.X())+(sc.Y()-center.Y())*(sc.Y()-center.Y())) <1.5*stupidRadius;
    }

    public int[] transform(PlaneCoord aS) {
        return transform.transformPoint(aS);
    }
    public PlaneCoord revTransform(Point p) {
        return transform.reverseTransform(p);
    }

    public double getDrawingScale() {
        return transform.getScaleFactor();
    }

    public void rotate30Deg() {
        theta = theta + ROTATE_UNIT;
        if(theta > 2*Math.PI){
            theta = theta - 2*Math.PI;
        }
        vp.repaint();
    }

    private void setRadius(double radius) {
        if(radius < 1){
            radius = 1.0;
        }
        stupidRadius = radius;
    }

    
}
